<template>
  <div ref="containerRef" class="monaco-editor-container" :style="containerStyle"></div>
</template>

<script setup>
import { ref, watch, onMounted, onBeforeUnmount, nextTick, computed } from 'vue';
import * as monaco from 'monaco-editor';

const props = defineProps({
  modelValue: { type: String, default: '' },
  language: { type: String, default: 'sql' },
  theme: { type: String, default: 'vs' },
  readOnly: { type: Boolean, default: false },
  fontSize: { type: Number, default: 16 },
  lineNumbers: { type: Boolean, default: true },
  autoHeight: { type: Boolean, default: true },
  minHeight: { type: Number, default: 120 },
  maxHeight: { type: Number, default: 600 },
});
const emit = defineEmits(['update:modelValue', 'change', 'select']);

const containerRef = ref(null);
let editor = null;

const containerStyle = computed(() => ({
  width: '100%',
  minHeight: props.minHeight + 'px',
  maxHeight: props.maxHeight + 'px',
  border: '1px solid #e8e8e8',
  borderRadius: '6px',
  background: '#fff',
  overflow: 'hidden',
  position: 'relative',
}));

function updateHeight() {
  if (!editor || !props.autoHeight) return;
  const lineCount = editor.getModel().getLineCount();
  const lineHeight = editor.getOption(monaco.editor.EditorOption.lineHeight);
  let height = lineCount * lineHeight + 16;
  height = Math.max(props.minHeight, Math.min(height, props.maxHeight));
  containerRef.value.style.height = height + 'px';
  editor.layout();
}

onMounted(async () => {
  await nextTick();
  editor = monaco.editor.create(containerRef.value, {
    value: props.modelValue,
    language: props.language,
    theme: props.theme,
    fontSize: props.fontSize,
    readOnly: props.readOnly,
    lineNumbers: props.lineNumbers ? 'on' : 'off',
    minimap: { enabled: false },
    scrollBeyondLastLine: false,
    wordWrap: 'on',
    automaticLayout: true,
    scrollbar: { vertical: 'auto', horizontal: 'auto' },
    contextmenu: true,
    tabSize: 2,
    renderLineHighlight: 'all',
    fixedOverflowWidgets: true,
  });
  editor.onDidChangeModelContent(() => {
    const value = editor.getValue();
    emit('update:modelValue', value);
    emit('change', value);
    updateHeight();
  });
  editor.onDidChangeCursorSelection(e => {
    const value = editor.getModel().getValueInRange(e.selection);
    emit('select', value);
  });
  editor.focus();
  updateHeight();
});

watch(() => props.modelValue, (val) => {
  if (editor && val !== editor.getValue()) {
    editor.setValue(val || '');
    updateHeight();
  }
});
watch(() => props.fontSize, (val) => {
  if (editor) editor.updateOptions({ fontSize: val });
});
watch(() => props.readOnly, (val) => {
  if (editor) editor.updateOptions({ readOnly: val });
});
watch(() => props.language, (val) => {
  if (editor) monaco.editor.setModelLanguage(editor.getModel(), val);
});
watch(() => props.theme, (val) => {
  if (editor) monaco.editor.setTheme(val);
});

onBeforeUnmount(() => {
  if (editor) {
    editor.dispose();
    editor = null;
  }
});
</script>

<style scoped>
.monaco-editor-container {
  width: 100%;
  min-height: 120px;
  background: #fff;
  border: 1px solid #e8e8e8;
  border-radius: 6px;
  overflow: hidden;
  position: relative;
}
</style> 